<?php
namespace Core\Extensions\Modules\WebDeveloper\Libs\Html;

class Html {

	private $flagInput = TRUE;
	private $flagOutput = TRUE;
	private $inputContent = NULL;
	private $outputContent = NULL;
	private $encoding = NULL;
	private $version = NULL;
	private $inputDOMElementPath = NULL;
	private $outputDOMElementPath = NULL;
	private $inputUuid = NULL;
	private $outputUuid = NULL;
	private $countFoundInputElements = 0;
	private $countFoundOutputElements = 0;
	private $limitToRemoveEqualsElements = 1;
	private $inputCodeElement = NULL;
	private $outputCodeElement = NULL;
	private $inputDOMNode = NULL;
	private $outputDOMNode = NULL;
	private $inputFilePath = NULL;
	private $outputFilePath = NULL;
	private $DOMDocument = NULL;
	private $inputDOMDocument = NULL;
	private $outputDOMDocument = NULL;
	private $backupInputFile = NULL;
	private $backupOutputFile = NULL;
	private $DOMXPath = NULL;
	private $status = FALSE;

	private $arrayReturn = array();

	private static $arrayPathsToUuids = array();

	final public function &getInputContent($string = NULL) {

		$this->inputContent =& $string;
	}

	final public function &getOutputContent($string = NULL) {

		$this->outputContent =& $string;
	}

	final public function setEncoding($encoding = 'UTF-8') {

		$this->encoding =& $encoding;
	}

	final public function getEncoding() {

		return $this->encoding;
	}

	final public function setVersion($version = NULL) {

		$this->version =& $version;
	}

	final public function getVersion() {

		return $this->version;
	}

	final public function setInputUuid($inputUuid = NULL) {

		if(!empty($inputUuid)) {

			$this->inputUuid =& $inputUuid;
		}
	}

	final public function getInputUuid() {

		return $this->inputUuid;
	}

	final public function setOutputUuid($outputUuid = NULL) {

		$this->outputUuid =& $outputUuid;
	}

	final public function getOutputUuid() {

		return $this->outputUuid;
	}

	final public function setInputDOMElementPath($inputDOMElementPath = NULL) {

		$this->inputDOMElementPath =& $inputDOMElementPath;
	}

	final public function getInputDOMElementPath() {

		return $this->inputDOMElementPath;
	}

	final public function setOutputDOMElementPath($outputDOMElementPath = NULL) {

		$this->outputDOMElementPath =& $outputDOMElementPath;
	}

	final public function getOutputDOMElementPath() {

		return $this->outputDOMElementPath;
	}

	final public function getInputFilePath() {

		return $this->inputFilePath;
	}

	final public function getOutputFilePath() {

		return $this->outputFilePath;
	}

	final public function getStatus() {

		return $this->status;
	}

	final public function getArrayReturn() {

		return $this->arrayReturn;
	}

	final public function getDOMXPath($param = NULL, $instanceOf = 'DOMXPath') {

		$numArgs =& func_num_args();

		if($this->DOMXPath instanceof $instanceOf && $numArgs > 0) {

			$this->DOMXPath->__construct($param);
		}

		elseif($numArgs > 0) {

			$this->DOMXPath = new \DOMXPath($param);
		}

		return $this->DOMXPath;
	}

	final public function removePathOfUuid($uuid = NULL) {

		if(!empty($uuid) && array_key_exists(&$uuid, &self::$arrayPathsToUuids)) {

			unset(self::$arrayPathsToUuids[$uuid]);
			return TRUE;
		}

		return FALSE;
	}

	final public function addPathOfUuid($uuid = NULL, $path = NULL) {

		if(!empty($uuid) && !empty($path)) {

			if(!is_array(self::$arrayPathsToUuids)) {

				self::$arrayPathsToUuids = array();
			}

			self::$arrayPathsToUuids[$uuid] = $path;
			return TRUE;
		}

		return FALSE;
	}

	final public function setPathOfUuid($uuid = NULL, $path = NULL) {

		if(!empty($uuid) && !empty($path) && array_key_exists(&$uuid, &self::$arrayPathsToUuids)) {

			self::$arrayPathsToUuids[$uuid] = $path;
			unset($uuid, $path);
			return TRUE;
		}

		unset($uuid, $path);
		return FALSE;
	}

	final public function getPathOfUuid($uuid = NULL) {

		if(!empty($uuid) && array_key_exists(&$uuid, &self::$arrayPathsToUuids)) {

			return self::$arrayPathsToUuids[$uuid];
		}

		unset($uuid);
		return NULL;
	}

	final public function reset() {

		$this->limitToRemoveEqualsElements = 1;
		$this->flagInput = TRUE;
		$this->flagOutput = TRUE;
		$this->inputContent = NULL;
		$this->outputContent = NULL;
		$this->encoding = NULL;
		$this->version = NULL;
		$this->inputDOMElementPath = NULL;
		$this->outputDOMElementPath = NULL;
		$this->inputUuid = NULL;
		$this->outputUuid = NULL;
		$this->countFoundInputElements = 0;
		$this->countFoundOutputElements = 0;
		$this->newCodeElement = NULL;
		$this->inputCodeElement = NULL;
		$this->outputCodeElement = NULL;
		$this->inputDOMNode = NULL;
		$this->outputDOMNode = NULL;
		$this->inputFilePath = NULL;
		$this->outputFilePath = NULL;
		$this->DOMDocument = NULL;
		$this->inputDOMDocument = NULL;
		$this->outputDOMDocument = NULL;
		$this->DOMXPath = NULL;

		unset($this);
		clearstatcache();
	}

	final public function shearchOfPathsToUuids() {

		
	}

	final public function init() {

		return call_user_func_array(array($this, '__construct'), func_get_args());
	}

	final public function __construct($inputUuid = NULL, $outputUuid = NULL, $inputCodeElement = NULL, $outputCodeElement = NULL, $limitToRemoveEqualsElements = 1, $method = 'appendToElement', $version = NULL, $encoding = 'UTF-8') {

		clearstatcache();

		if(func_num_args() === 2) {

			$this->version = func_get_arg(0);
			$this->encoding = func_get_arg(1);

			return;
		}

		$this->shearchOfPathsToUuids();

		if(is_numeric($limitToRemoveEqualsElements)) {

			$this->limitToRemoveEqualsElements = (int)$limitToRemoveEqualsElements;
		}

		$flagInput = TRUE;
		$flagOutput = TRUE;

		if($method === 'removeElement') {

			$flagOutput = FALSE;
		}

		elseif(substr($method, 0, 3) === 'add') {

			$flagInput = FALSE;
		}

		if(!method_exists(&$this, &$method)) {

			throw \Core\Uses\Exception('Error: Método requisitado para manipulação dos elementos não foi encontrado. OBS: Method: ' . $method, E_ERROR, 100, __FILE__, __LINE__);
		}

		if(empty($inputUuid)) {

			throw \Core\Uses\Exception('Error: UUID do elemento que será movido não foi informado.' . $inputUuid, E_ERROR, 100, __FILE__, __LINE__);
		}

		elseif(empty($outputUuid) && $flagOutput) {

			throw \Core\Uses\Exception('Error: UUID do elemento para onde será movido o elemento selecionado não foi informado.' . $inputUuid, E_ERROR, 100, __FILE__, __LINE__);
		}

		elseif($flagInput && $flagOutput) {

			$this->inputUuid = $inputUuid;
			$this->outputUuid = $outputUuid;
			$this->version = $version;
			$this->encoding = $encoding;
			$this->readPathsToUuids();
			$this->inputFilePath = $this->getPathOfUuid($inputUuid);
			$this->outputFilePath = $this->getPathOfUuid($outputUuid);
		}

		elseif($flagInput) {

			$this->inputUuid = $inputUuid;
			$this->version = $version;
			$this->encoding = $encoding;
			$this->readPathsToUuids();
			$this->inputFilePath = $this->getPathOfUuid($inputUuid);
		}

		elseif($flagOutput) {

			$this->outputUuid = $outputUuid;
			$this->version = $version;
			$this->encoding = $encoding;
			$this->readPathsToUuids();
			$this->outputFilePath = $this->getPathOfUuid($outputUuid);

			if(!empty($inputCodeElement)) {

				$this->inputUuid = $inputUuid;
			}
		}

		if(empty($this->inputFilePath) && $flagInput) {

			throw \Core\Uses\Exception('Error: Arquivo não encontrado. OBS: INPUT ELEMENT, UUID: ' . $inputUuid, E_ERROR, 100, __FILE__, __LINE__);
		}

		if(empty($this->outputFilePath) && $flagOutput) {

			throw \Core\Uses\Exception('Error: Arquivo não encontrado. OBS: OUTPUT ELEMENT, UUID: ' . $outputUuid, E_ERROR, 100, __FILE__, __LINE__);
		}

		$this->flagInput = $flagInput;
		$this->flagOutput = $flagOutput;

		if($flagInput || (!$flagInput && !empty($inputCodeElement))) {

			if(!empty($inputCodeElement)) {

				$this->inputContent = $inputCodeElement;
			}

			else {

				$this->inputContent = $this->getFileContents($this->inputFilePath);
			}

			$this->backupInputFile = $this->inputContent;
			$this->inputCodeElement = $this->getInputCodeElement(FALSE);

			if($this->countFoundInputElements < 1) {

				throw \Core\Uses\Exception('Error: UUID do elemento selecionado não foi encontrado no arquivo. OBS: INPUT ELEMENT, UUID: ' . $inputUuid, E_ERROR, 100, __FILE__, __LINE__);
			}
		}

		if($flagOutput) {

			$this->outputContent = $this->getFileContents($this->outputFilePath);
			$this->backupOutputFile = $this->outputContent;
			$this->outputCodeElement = $this->getOutputCodeElement(FALSE);

			if($this->countFoundOutputElements < 1) {

				throw \Core\Uses\Exception('Error: UUID do elemento selecionado não foi encontrado no arquivo. OBS: OUTPUT ELEMENT, UUID: ' . $outputUuid, E_ERROR, 100, __FILE__, __LINE__);
			}
		}

		$this->$method();
		$this->reset();
	}

	final public function enablePhpTags($string = NULL) {

		return preg_replace(array('/[\n\r\t]*(\<\!\-\-\@\_\_\[\!\!\!PHPSCRIPT_GENERATED_BY_FRAMEWORK_JABEZ_PHP\!\!\!\])(\<\?(?:php)?)/i', '/(\?\>)(\@\_\_\[\!\!\!PHPSCRIPT_GENERATED_BY_FRAMEWORK_JABEZ_PHP\!\!\!\]\-\-\>)[\n\r\t]*/i'), array("\n".'\2', '\1'."\n"), $string);
	}

	final public function disablePhpTags($string = NULL) {

		return preg_replace(array('/[\n\r\t]*(\<\?(?:php)?)/i', '/(\?\>)[\n\r\t]*/'), array('<!--@__[!!!PHPSCRIPT_GENERATED_BY_FRAMEWORK_JABEZ_PHP!!!]'.'\1', '\1'.'@__[!!!PHPSCRIPT_GENERATED_BY_FRAMEWORK_JABEZ_PHP!!!]-->'), $string);
	}

	final public function loadHTML($string, $isFile = FALSE, $suppressErros = TRUE, $checkErros = TRUE) {

		if(!$isFile) {

			$this->DOMDocument = new \DOMDocument($this->version, $this->encoding);
			//$this->DOMDocument->preserveWhiteSpace = FALSE;
			//$this->DOMDocument->formatOutput = TRUE;

			if(empty($string)) {

				$string = '<html></html>';
			}

			$string = $this->disablePhpTags(&$string);

			try {

				$this->DOMDocument->loadHTML($string);
			}

			catch(\Exception $e) {}
		}

		else {

			$string = $this->getFileContents($string, TRUE);

			if(empty($string)) {

				$string = '<html></html>';
			}

			$this->loadHTML($string, FALSE, $suppressErros, $checkErros);
		}
	}

	final public function appendToElement() {

		$this->removeElement();

		try {

			$this->getDOMXPath($this->outputDOMDocument);
			$query = $this->getDOMXPath()->query('//*[@uuid="'.$this->outputUuid.'"]')->item(0);
			$query->appendChild($this->outputDOMDocument->importNode($this->inputDOMNode, TRUE));
			$query = $this->getDOMXPath()->query('/html/body/*', $query)->item(0);
			$this->outputContent = trim($this->enablePhpTags($this->outputDOMDocument->saveHTML($query)));
			$this->saveDOM('output');
			$this->setPathOfUuid($this->inputUuid, $this->outputFilePath);
		}

		catch(\Exception $e) {

			$this->saveBackupFile('all');
		}

		try {

			if(!$this->addToClipboard()) {

				trigger_error('Error: Problema ao salvar elemento na área de transferência.', E_USER_WARNING);
			}
		}

		catch(\Exception $e) {

			throw \Core\Uses\Exception('Error: Problema ao salvar elemento na área de transferência.', E_NOTICE, 25, __FILE__, __LINE__);
		}

		unset($query);
	}

	final public function appendBeforeOfElement() {

		$this->removeElement();

		try {

			$this->getDOMXPath($this->outputDOMDocument);
			$query = $this->getDOMXPath()->query('//*[@uuid="'.$this->outputUuid.'"]')->item(0);
			$query->parentNode->insertBefore($this->outputDOMDocument->importNode($this->inputDOMNode, TRUE), $query);
			$query = $this->getDOMXPath()->query('/html/body/*', $query)->item(0);
			$this->outputContent = trim($this->enablePhpTags($this->outputDOMDocument->saveHTML($query)));
			$this->saveDOM('output');
			$this->setPathOfUuid($this->inputUuid, $this->outputFilePath);
		}

		catch(\Exception $e) {

			$this->saveBackupFile('all');
		}

		try {

			if(!$this->addToClipboard()) {

				trigger_error('Error: Problema ao salvar elemento na área de transferência.', E_USER_WARNING);
			}
		}

		catch(\Exception $e) {

			throw \Core\Uses\Exception('Error: Problema ao salvar elemento na área de transferência.', E_NOTICE, 25, __FILE__, __LINE__);
		}

		unset($query);
	}

	final public function appendAfterOfElement() {

		$this->removeElement();

		try {

			$this->getDOMXPath($this->outputDOMDocument);
			$query = $this->getDOMXPath()->query('//*[@uuid="'.$this->outputUuid.'"]')->item(0);
			$query->parentNode->insertBefore($this->outputDOMDocument->importNode($this->inputDOMNode, TRUE), $query->nextSibling);
			$query = $this->getDOMXPath()->query('/html/body/*', $query)->item(0);
			$this->outputContent = trim($this->enablePhpTags($this->outputDOMDocument->saveHTML($query)));
			$this->saveDOM('output');
			$this->setPathOfUuid($this->inputUuid, $this->outputFilePath);
		}

		catch(\Exception $e) {

			$this->saveBackupFile('all');
		}

		try {

			if(!$this->addToClipboard()) {

				trigger_error('Error: Problema ao salvar elemento na área de transferência.', E_USER_WARNING);
			}
		}

		catch(\Exception $e) {

			throw \Core\Uses\Exception('Error: Problema ao salvar elemento na área de transferência.', E_NOTICE, 25, __FILE__, __LINE__);
		}

		unset($query);
	}

	final public function addToElement() {

		try {

			$this->getDOMXPath($this->outputDOMDocument);
			$query = $this->getDOMXPath()->query('//*[@uuid="'.$this->outputUuid.'"]')->item(0);
			$query->appendChild($this->outputDOMDocument->importNode($this->inputDOMNode, TRUE));
			$query = $this->getDOMXPath()->query('/html/body/*', $query)->item(0);
			$this->outputContent = trim($this->enablePhpTags($this->outputDOMDocument->saveHTML($query)));
			$this->saveDOM('output');
			$this->inputFilePath = $this->outputFilePath;
			$this->setPathOfUuid($this->inputUuid, $this->outputFilePath);
		}

		catch(\Exception $e) {

			$this->saveBackupFile('output');
		}

		try {

			if(!$this->addToClipboard()) {

				trigger_error('Error: Problema ao salvar elemento na área de transferência.', E_USER_WARNING);
			}
		}

		catch(\Exception $e) {

			throw \Core\Uses\Exception('Error: Problema ao salvar elemento na área de transferência.', E_NOTICE, 25, __FILE__, __LINE__);
		}

		unset($query);
	}

	final public function addBeforeOfElement() {

		try {

			$this->getDOMXPath($this->outputDOMDocument);
			$query = $this->getDOMXPath()->query('//*[@uuid="'.$this->outputUuid.'"]')->item(0);
			$query->parentNode->insertBefore($this->outputDOMDocument->importNode($this->inputDOMNode, TRUE), $query);
			$query = $this->getDOMXPath()->query('/html/body/*', $query)->item(0);
			$this->outputContent = trim($this->enablePhpTags($this->outputDOMDocument->saveHTML($query)));
			$this->saveDOM('output');
			$this->inputFilePath = $this->outputFilePath;
			$this->setPathOfUuid($this->inputUuid, $this->outputFilePath);
		}

		catch(\Exception $e) {

			$this->saveBackupFile('output');
		}

		try {

			if(!$this->addToClipboard()) {

				trigger_error('Error: Problema ao salvar elemento na área de transferência.', E_USER_WARNING);
			}
		}

		catch(\Exception $e) {

			throw \Core\Uses\Exception('Error: Problema ao salvar elemento na área de transferência.', E_NOTICE, 25, __FILE__, __LINE__);
		}

		unset($query);
	}

	final public function addAfterOfElement() {

		try {

			$this->getDOMXPath($this->outputDOMDocument);
			$query = $this->getDOMXPath()->query('//*[@uuid="'.$this->outputUuid.'"]')->item(0);
			$query->parentNode->insertBefore($this->outputDOMDocument->importNode($this->inputDOMNode, TRUE), $query->nextSibling);
			$query = $this->getDOMXPath()->query('/html/body/*', $query)->item(0);
			$this->outputContent = trim($this->enablePhpTags($this->outputDOMDocument->saveHTML($query)));
			$this->saveDOM('output');
			$this->inputFilePath = $this->outputFilePath;
			$this->setPathOfUuid($this->inputUuid, $this->outputFilePath);
		}

		catch(\Exception $e) {

			$this->saveBackupFile('output');
		}

		try {

			if(!$this->addToClipboard()) {

				trigger_error('Error: Problema ao salvar elemento na área de transferência.', E_USER_WARNING);
			}
		}

		catch(\Exception $e) {

			throw \Core\Uses\Exception('Error: Problema ao salvar elemento na área de transferência.', E_NOTICE, 25, __FILE__, __LINE__);
		}

		unset($query);
	}

	final public function removeElement() {

		try {

			$this->getDOMXPath($this->inputDOMDocument);

			if($this->limitToRemoveEqualsElements < 1) {

				$limitToRemoveEqualsElements = -1;
			}

			else {

				$limitToRemoveEqualsElements = $this->limitToRemoveEqualsElements;
			}

			$this->inputContent = trim($this->enablePhpTags(preg_replace('/[\n\r\t]*' . preg_quote($this->inputCodeElement, '/') . '/', '', $this->inputDOMDocument->saveHTML($this->getDOMXPath()->query('/html/body/*')->item(0)), $limitToRemoveEqualsElements)));
			$this->saveDOM('input');
			$this->removePathOfUuid($this->inputUuid);
		}

		catch(\Exception $e) {

			$this->saveBackupFile('input');
			$this->addPathOfUuid($this->inputUuid, $this->inputFilePath);
			throw \Core\Uses\Exception('Error: Não foi possivel remover o elemento do arquivo. ELEMENT UUID: ' . $this->inputUuid . ' - PATH: ' . $this->inputFilePath, E_WARNING, 100, __FILE__, __LINE__);
		}
	}

	final public function getFileContents($string = NULL, $isPath = TRUE) {

		if(!empty($string)) {

			clearstatcache();

			if(!$isPath) {

			}

			if(is_file(&$string) && file_exists(&$string) && is_readable(&$string) && !is_executable(&$string)) {

				try {

					$content = file_get_contents($string);
				}

				catch(\Exception $e) {

					throw \Core\Uses\Exception('Error: Falha ao abrir o arquivo: ' . $string, E_WARNING, 100, __FILE__, __LINE__);
				}

				try {

					$content = mb_convert_encoding($content, $this->encoding);
				}

				catch(\Exception $e) {

					throw \Core\Uses\Exception('Error: Erro na codificação do arquivo: ' . $string, E_WARNING, 100, __FILE__, __LINE__);
				}

				clearstatcache();
				$string = $content;
				unset($content);

				return $string;
			}
		}

		return NULL;
	}

	final public function saveFileContents($string = NULL, $data = NULL) {

		clearstatcache();

		try {

			if(is_writable(&$string)) {

				file_put_contents(&$string, &$data);
			}

			else {

				throw \Core\Uses\Exception('Error: Arquivo não pode ser alterado. OBS: OUTPUT FILE CONTENTS, PATH: ' . $string, E_WARNING, 100, __FILE__, __LINE__);
			}
		}

		catch(\Exception $e) {

			throw \Core\Uses\Exception('Error: Arquivo não pode ser alterado. OBS: OUTPUT FILE CONTENTS, PATH: ' . $string, E_WARNING, 100, __FILE__, __LINE__);
		}

		clearstatcache();
	}

	final public function saveBackupFile($file = 'all', $attempts = 3, $waitSeconds = 1, $count = 1, $input = TRUE, $output = TRUE) {

		if($file === 'all' || $file === 'input') {

			if($input) {

				$count = 1;
			}

			try {

				$this->saveFileContents($this->inputFilePath, $this->backupInputFile);
				$input = TRUE;
			}

			catch(\Exception $e) {

				if($count <= $attempts) {

					sleep($waitSeconds);
					$count++;
					$this->saveBackupFile($file, $attempts, $waitSeconds, $count, FALSE, TRUE);
				}

				else {

					throw \Core\Uses\Exception('Error: DOM não pode ser gravado no arquivo. OBS: INPUT FILE, PATH: ' . $this->inputFilePath, E_ERROR, 100, __FILE__, __LINE__);
				}
			}
		}

		if($file === 'all' || $file === 'output') {

			if($output) {

				$count = 1;
			}

			try {

				$this->saveFileContents($this->outputFilePath, $this->backupOutputFile);
				$output = TRUE;
			}

			catch(\Exception $e) {

				if($count <= $attempts) {

					sleep($waitSeconds);
					$count++;
					$this->saveBackupFile($file, $attempts, $waitSeconds, $count, TRUE, FALSE);
				}

				else {

					throw \Core\Uses\Exception('Error: DOM não pode ser gravado no arquivo. OBS: INPUT FILE, PATH: ' . $this->outputFilePath, E_ERROR, 100, __FILE__, __LINE__);
				}
			}
		}
	}

	final public function saveDOM($dom = 'all', $file = NULL, $data = NULL) {

		if($dom === 'all' || $dom === 'input') {

			$updateDOM = TRUE;

			if(empty($file)) {

				$file = $this->inputFilePath;
			}

			else {

				$updateDOM = FALSE;
			}

			if(empty($data)) {

				$data = $this->inputContent;
			}

			else {

				$updateDOM = FALSE;
			}

			try {

				$this->saveFileContents($file, $data);
			}

			catch(\Exception $e) {

				throw \Core\Uses\Exception('Error: DOM não pode ser gravado no arquivo. OBS: INPUT FILE, PATH: ' . $this->inputFilePath, E_ERROR, 100, __FILE__, __LINE__);
			}

			try {

				if($updateDOM) {

					$this->updateDOM();
				}
			}

			catch(\Exception $e) {

				throw \Core\Uses\Exception('Error: DOM não pode ser carregado. OBS: OUTPUT FILE, PATH: ' . $this->outputFilePath, E_ERROR, 100, __FILE__, __LINE__);
			}

			unset($file, $data);
		}

		if($dom === 'all' || $dom === 'output') {

			if(empty($file)) {

				$file = $this->outputFilePath;
			}

			if(empty($data)) {

				$data = $this->outputContent;
			}

			try {

				$this->saveFileContents($file, $data);
			}

			catch(\Exception $e) {

				throw \Core\Uses\Exception('Error: DOM não pode ser gravado no arquivo. OBS: OUTPUT FILE, PATH: ' . $this->outputFilePath, E_ERROR, 100, __FILE__, __LINE__);
			}

			unset($file, $data);
		}
	}

	final public function updateDOM() {

		if($this->inputFilePath !== $this->outputFilePath) {

			$this->outputContent = $this->getFileContents($this->outputFilePath);
			$this->loadHTML($this->outputContent);
			$this->outputDOMDocument = $this->DOMDocument;
		}

		else {

			$this->outputContent = $this->inputContent;
			$this->loadHTML($this->outputContent);
			$this->outputDOMDocument = $this->DOMDocument;
		}
	}

	final public function getInputCodeElement($getValue = TRUE) {

		if(!$getValue) {

			try {

				$this->loadHTML($this->inputContent);
				$this->inputDOMDocument = $this->DOMDocument;
				$this->getDOMXPath($this->inputDOMDocument);
				$query = $this->getDOMXPath()->query('//*[@uuid="'.$this->inputUuid.'"]')->item(0);

				if(is_object($query)) {

					$this->countFoundInputElements = (int)$this->getDOMXPath()->evaluate('count(//*[@uuid="'.$this->inputUuid.'"])', $query);

					if(empty($query->previousSibling)) {

						$this->inputDOMElementPath = $query->getNodePath();
					}

					else {

						$this->inputDOMElementPath = $query->previousSibling->getNodePath();
					}

					$this->inputDOMNode = $query;

					return $this->DOMDocument->saveHTML($query);
				}

				elseif((int)$this->getDOMXPath()->evaluate('count(//*[@uuid="'.$this->inputUuid.'"])', $query) > 0) {

					trigger_error('Error: Problema ao obter o código do elemento. OBS: INPUT ELEMENT.', E_USER_WARNING);
				}
			}

			catch(\Exception $e) {

				throw \Core\Uses\Exception('Error: Problema ao obter o código do elemento. OBS: INPUT ELEMENT.', E_WARNING, 100, __FILE__, __LINE__);
			}
		}

		return $this->inputCodeElement;
	}

	final public function getOutputCodeElement($getValue = TRUE) {

		if(!$getValue) {

			try {

				$this->loadHTML($this->outputContent);
				$this->outputDOMDocument = $this->DOMDocument;
				$this->getDOMXPath($this->outputDOMDocument);
				$query = $this->getDOMXPath()->query('//*[@uuid="'.$this->outputUuid.'"]')->item(0);

				if(is_object($query)) {

					$this->countFoundOutputElements = (int)$this->getDOMXPath()->evaluate('count(//*[@uuid="'.$this->outputUuid.'"])', $query);

					if(empty($query->previousSibling)) {

						$this->outputDOMElementPath = $query->getNodePath();
					}

					else {

						$this->outputDOMElementPath = $query->previousSibling->getNodePath();
					}

					$this->outputDOMNode = $query;

					return $this->DOMDocument->saveHTML($query);
				}

				elseif((int)$this->getDOMXPath()->evaluate('count(//*[@uuid="'.$this->outputUuid.'"])', $query) > 0) {

					trigger_error('Error: Problema ao obter o código do elemento. OBS: OUTPUT ELEMENT.', E_USER_WARNING);
				}
			}

			catch(\Exception $e) {

				throw \Core\Uses\Exception('Error: Problema ao obter o código do elemento. OBS: OUTPUT ELEMENT.', E_WARNING, 100, __FILE__, __LINE__);
			}
		}

		$this->outputCodeElement;
	}

	final public function getUuidsOfFile($file = NULL) {

		$arrayPathsToUuids = array();
		$this->loadHTML($file, TRUE);
		$DOMXPath = $this->getDOMXPath($this->DOMDocument);
		$query = $DOMXPath->query('//*[@uuid]');

		foreach($query as $element) {

			$arrayPathsToUuids[trim($element->getAttribute('uuid'))] = $file;
		}

		self::$arrayPathsToUuids =& array_merge(self::$arrayPathsToUuids, &$arrayPathsToUuids);
		unset($arrayPathsToUuids, $query, $element, $file, $DOMXPath);
	}

	final public function getUuidsOfFiles($arrayFiles = array()) {

		if(!is_array($arrayFiles)) {

			$arrayFiles = array();
		}

		$arrayFiles[] = 'D:\xampp\htdocs\jabez-php\jabez\app\extensions\modules\web-developer\app\design\views\html\uuid_01.php';

		foreach($arrayFiles as $file) {

			$this->getUuidsOfFile($file);
		}

		unset($arrayFiles, $file);
	}

	final public function readPathsToUuids() {

		$arrayPathsToUuids = \Core\Uses\Ler('Core.extensions.modules.web-developer.config.pathOfUuids', TRUE, 'array');

		if(is_array($arrayPathsToUuids['_value'])) {

			self::$arrayPathsToUuids = $arrayPathsToUuids['_value'];
		}

		else {

			self::$arrayPathsToUuids = array();
		}

		unset($arrayPathsToUuids);
	}

	final public function writePathsToUuids() {

		
	}

	final public function addToClipboard($inputDOMElementPath = NULL, $inputFilePath = NULL, $inputUuid = NULL, $outputFilePath = NULL, $getNext = TRUE) {

		if(!empty($inputDOMElementPath) && !empty($inputFilePath) && !empty($inputUuid) && !empty($outputFilePath)) {

			$this->inputDOMElementPath = $inputDOMElementPath;
			$this->inputFilePath = $inputFilePath;
			$this->inputUuid = $inputUuid;
			$this->outputUuid = $outputFilePath;
		}

		else {

			$getNext = TRUE;
		}

		return \Core\Extensions\Modules\WebDeveloper\Libs\Clipboard\Html::add($this->inputDOMElementPath, $this->inputFilePath, $this->inputUuid, $this->outputFilePath, $getNext);
	}
}
?>